package com.tongji.diy.model.furniturePlacementOptimization.accessibleBoundingBoxes
{
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import com.tongji.diy.model.furniturePlacementOptimization.OptimizationParameter;
	
	public class FurnitureAcessibleBoundingBoxA extends FurnitureBasicBoundingBox
	{
		private var _accessibleBoxCenters:Vector.<Point>;
		private var accessDistance:Number;
		private var _accessDiagonals:Vector.<Number> = new Vector.<Number>;
	
		public function FurnitureAcessibleBoundingBoxA(location:Vector3D, width:Number, length:Number, height:Number, angle:Number, parentRoomIndex:int, pairFurnitureIndex:int, furnitureClass:int)
		{
			super(location, width, length, height, angle, parentRoomIndex, pairFurnitureIndex, furnitureClass);
			accessDistance = OptimizationParameter.acessibleDistanceA;
			_accessibleBoxCenters = buildAcessibleBoxCenters(this.location,this.width,this.length, this.angle);
			var tempDiagonal1:Number = Math.sqrt(this.width*this.width/4 + (this.length/2 + accessDistance)*(this.length/2 + accessDistance)/4);
			var tempDiagonal2:Number = Math.sqrt(this.length*this.length/4 + (this.width/2 + accessDistance)*(this.width/2 + accessDistance)/4);
			_accessDiagonals.push(tempDiagonal1,tempDiagonal2,tempDiagonal1,tempDiagonal2);
			this.accessibleBoundingBox = accessibleOBB2D(this.location,this.width,this.length, this.angle);
		}
		
		public override function clone():FurnitureBasicBoundingBox
		{
			return new FurnitureAcessibleBoundingBoxA(location,width,length,height,angle,parentRoomIndex,pairFurnitureIndex, furnitureClass);
		}
		
//		public function get accessibleBoundingBox():Vector.<Point>
//		{
//			return _accessibleBoundingBox;
//		}
		
		public function get accessibleBoxCenters():Vector.<Point>
		{
			return _accessibleBoxCenters;
		}
		
		private function accessibleOBB2D(location:Vector3D, width:Number, length:Number, angle:Number):Vector.<Point>
		{
			var AABB:Vector.<Point> = new Vector.<Point>;
			var leftTop:Point = new Point(location.x - width/2 - accessDistance, location.y + length/2 + accessDistance);
			AABB.push(leftTop);
			var rightTop:Point = new Point(location.x + width/2 + accessDistance, location.y + length/2 + accessDistance);
			AABB.push(rightTop);
			var rightBottom:Point = new Point(location.x + width/2 + accessDistance, location.y - length/2 - accessDistance);
			AABB.push(rightBottom);
			var leftBottom:Point = new Point(location.x - width/2 - accessDistance, location.y - length/2 - accessDistance);
			AABB.push(leftBottom);
			
			var moveM1:Matrix = new Matrix();
			moveM1.translate(-location.x, -location.y);
			var moveM2:Matrix = new Matrix();
			moveM2.translate(location.x, location.y);
			var rotateM:Matrix = new Matrix();
			rotateM.rotate(-angle);
			moveM1.concat(rotateM);
			moveM1.concat(moveM2);
			var transM:Matrix = moveM1;
			for(var i:int = 0;i<AABB.length;i++)
			{
				AABB[i] = transM.transformPoint(AABB[i]);
			}
			accessMaxX = -Infinity;
			accessMaxY = -Infinity;
			accessMinX = Infinity;
			accessMinY = Infinity;
			
			for(i = 0;i<AABB.length;i++)
			{
				AABB[i] = transM.transformPoint(AABB[i]);
				if(accessMaxX < AABB[i].x)
					accessMaxX = AABB[i].x;
				if(accessMinX > AABB[i].x)
					accessMinX = AABB[i].x;
				if(accessMaxY < AABB[i].y)
					accessMaxY = AABB[i].y;
				if(accessMinY > AABB[i].y)
					accessMinY = AABB[i].y;
			}
			return AABB;
		}		
		
		private function buildAcessibleBoxCenters(location:Vector3D, width:Number, length:Number, angle:Number):Vector.<Point>
		{
			var AABB:Vector.<Point> = new Vector.<Point>;
			var left:Point = new Point((2*location.x - width/2 - accessDistance)/2, location.y);
			var right:Point = new Point((2*location.x + width/2 + accessDistance)/2, location.y);
			var up:Point = new Point(location.x, (2*location.y + length/2 + accessDistance)/2);
			var down:Point = new Point(location.x, (2*location.y - length/2 - accessDistance)/2);

			AABB.push(up, left, down, right);
			
			var moveM1:Matrix = new Matrix();
			moveM1.translate(-location.x, -location.y);
			var moveM2:Matrix = new Matrix();
			moveM2.translate(location.x, location.y);
			var rotateM:Matrix = new Matrix();
			rotateM.rotate(-angle);
			moveM1.concat(rotateM);
			moveM1.concat(moveM2);
			var transM:Matrix = moveM1;
			
			for(var i:int = 0;i<AABB.length;i++)
			{
				AABB[i] = transM.transformPoint(AABB[i]);
			}
			
			return AABB;
		}
		
		public function get accessDiagonals():Vector.<Number>
		{
			return _accessDiagonals;
		}
		
		public override function set location(location:Vector3D):void
		{
			super.location = location;
			this.accessibleBoundingBox = accessibleOBB2D(this.location, this.width, this.length, this.angle);
			_accessibleBoxCenters = buildAcessibleBoxCenters(this.location,this.width,this.length, this.angle);
		}
		
		public override function set angle(angle:Number):void
		{
			super.angle = angle;
			this.accessibleBoundingBox = accessibleOBB2D(this.location, this.width, this.length, this.angle);	
			_accessibleBoxCenters = buildAcessibleBoxCenters(this.location,this.width,this.length, this.angle);
		}
	}
}